package com.sanploy.manage.conf.security;

import com.sanploy.common.enums.AdminRole;
import com.sanploy.manage.service.impl.AdminDetailImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by zhu yingzhi on 2017/10/16.
 * @author yingzhi zhu
 * spring security 权限配置类 实现登陆控制 访问地址权限控制
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter{

    @Bean
    AdminDetailImpl AdminDetailImpl(){
        return new AdminDetailImpl();
    }

    /**
     * 用自定义的登陆处理接口去覆盖默认的处理方法
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(AdminDetailImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //取消csrf
        http.csrf().disable();
        //配置安全策略 权限配置
        http.authorizeRequests()
                //定义请求不需要验证
                .antMatchers("/m/**").permitAll()
                //必须登陆了才能访问 html页面
                .antMatchers("/back/view/index/**").authenticated()

                .antMatchers("/goods","/goods/**","/back/view/goods/**").hasAnyRole(AdminRole.GOODS.toString(),AdminRole.SUPER.toString())

                .antMatchers("/banner","/banner/**","/back/view/banner/**").hasAnyRole(AdminRole.BANNER.toString(),AdminRole.SUPER.toString())

                .antMatchers("/order","/order/**","/back/view/order/**").hasAnyRole(AdminRole.ORDER.toString(),AdminRole.SUPER.toString())

                .antMatchers("/user","/user/**","/back/view/user/**").hasAnyRole(AdminRole.USER.toString(),AdminRole.SUPER.toString())

                .antMatchers("/freight","/freight/**","/back/view/freight/**").hasAnyRole(AdminRole.FREIGHT.toString(),AdminRole.SUPER.toString())

                .antMatchers("/message","/message/**","/messageSocket","/messageSocket/**","/back/view/message/**").hasAnyRole(AdminRole.MESSAGE.toString(),AdminRole.SUPER.toString())

//                .antMatchers("/category","/category/**","/back/view/category/**").hasAnyRole(AdminRole.CATEGORY.toString(),AdminRole.SUPER.toString())

                .antMatchers("/sys_config","/sys_config/**","/admin","/admin/**","/back/view/admin/**","/back/view/conf/**").hasRole(AdminRole.SUPER.toString())

//                .anyRequest().authenticated()//其余的所有请求都需要验证
                .and()
                .logout()
                .permitAll()//定义logout不需要验证
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
//                .defaultSuccessUrl("/back/index.html")
                    .loginPage("/back/view/login.html")
                .permitAll()
                .failureHandler(new FailureHandle()).
                //使用form表单登录
                successHandler(new SuccessfulHandle());

    }

    /**
     * 登陆成功后处理方法
     */
    private class SuccessfulHandle implements    AuthenticationSuccessHandler {

        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                            Authentication authentication) throws IOException, ServletException {
            StringBuilder authority = new StringBuilder();
            for(GrantedAuthority grantedAuthority:authentication.getAuthorities()){
                authority.append(grantedAuthority.getAuthority()).append(",");
            }
            String authoritys = authority.deleteCharAt(authority.length()-1).toString();
            User user = (User) authentication.getPrincipal();
            String successful = "{\"code\":\"200\",\"message\":\"成功\",\"authoritys\":\""+authoritys+"\",\"username\":\""+user.getUsername()+"\"}";
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(successful);
        }
    }

    /**
     * 登陆失败后处理方法
     */
    private class FailureHandle implements AuthenticationFailureHandler {

        @Override
        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
            String fail = "{\"code\":\"500\",\"message\":\"失败\",\"authoritys\":\"\",\"username\":\"heheda\"}";
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(fail);
        }
    }

}
